package com.zhangx.study.demo.rpc.client;

import com.zhangx.study.demo.rpc.server.model.User;
import com.zhangx.study.demo.rpc.server.service.IUserService;
import com.zhangx.study.demo.rpc.server.service.UserServiceImpl;
import lombok.extern.slf4j.Slf4j;

import java.io.DataInputStream;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;

/**
 * @ClassName StubV5
 * @Description TODO
 * @Author zhangx
 * @Date 2020/10/12 8:44
 **/
@Slf4j
public class StubV5 {
    public static IUserService getStub(){
//        创建代理类
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                User user = new User();
                Socket socket = new Socket("localhost",8888);
//                这里要给服务端写入对象了
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                oos.writeUTF(UserServiceImpl.class.getName());
//                传入的要调用服务端的方法名
                oos.writeUTF(method.getName());
//                参数类型
                Class[] parameterTypes = method.getParameterTypes();
                oos.writeObject(parameterTypes);
//                参数值
                oos.writeObject(args);
                oos.flush();
//            从服务端读取
                InputStream in = socket.getInputStream();
                DataInputStream dataInputStream = new DataInputStream(in);
                int age = dataInputStream.readInt();
                String name = dataInputStream.readUTF();
                log.info("收到服务端返回 age={},name={}",age,name);
                oos.close();
                socket.close();

                user.setAge(age);
                user.setName(name);
                return user;
            }
        };
//        执行代理，构建对象
        Object o = Proxy.newProxyInstance(IUserService.class.getClassLoader(),new Class[]{IUserService.class},handler);
        return (IUserService)o;
    }
}
